package xcmg.device.service.purchase;

import com.github.pagehelper.PageInfo;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.company.CompanySupplierDO;
import xcmg.device.dao.entity.purchase.PurchasePriceDO;
import xcmg.device.dao.mapper.CompanySupplierMapper;
import xcmg.device.dao.mapper.PurchasePriceMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.FileUtil;
import xcmg.device.service.basic.MaterialsService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.basic.MaterialsVO;
import xcmg.device.service.vo.purchase.PurchasePriceVO;
import xcmg.device.util.ToolPrice;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.PageHelperPlus;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class PurchasePriceService {
    @Autowired
    private FastGenClient fastGenClient;

    @Autowired
    private MaterialsService materialsService;

    @Autowired
    private CompanySupplierMapper companySupplierMapper;

    private String templateExcelFileName = "PurchasePrice.xls";

    @Autowired
    private HttpServletResponse response;

    @Value("${spring.file.download.path}")
    private String filePath;

    @Autowired
    private PurchasePriceMapper purchasePriceMapper;

    /**
     * @param condition
     * @return
     * @return PageCommonVO 返回类型
     * @description 查询采购价维护数据
     */
    public PageCommonVO<PurchasePriceDO> list(SearchCommonVO<PurchasePriceDO> condition) {
        PageCommonVO result = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        // 查询采购价格维护数据
        List<PurchasePriceDO> purchasePriceList = purchasePriceMapper.list(condition.getFilters());
        List<PurchasePriceVO> priceVOS = new ArrayList<>();
        if (purchasePriceList != null) {
            for (PurchasePriceDO purchasePriceDO : purchasePriceList) {
                PurchasePriceVO priceVO = new PurchasePriceVO();
                BeanUtils.copyProperties(purchasePriceDO, priceVO);
                priceVOS.add(priceVO);
            }
        }
        result.setPageInfo(new PageInfo(purchasePriceList));
        result.setPageInfoList(priceVOS);
        return result;
    }

    /**
     * @return queryCond 采购价格维护信息对象
     * @description 根据主键查询采购价格
     */
    public PurchasePriceDO itemForPurchasePrice(PurchasePriceDO queryCond) {
        PurchasePriceDO purchasePrice = null;
        List<PurchasePriceDO> list = purchasePriceMapper.selectListByExact(queryCond);
        if (null != list && list.size() == 1) {
            purchasePrice = list.get(0);
            purchasePrice.setPrice(ToolPrice.shwoPriceHandle(purchasePrice.getPrice()));
        }
        return purchasePrice;
    }

    public List<PurchasePriceDO> selectListByExact(PurchasePriceDO purchasePriceDO) {
        return purchasePriceMapper.selectListByExact(purchasePriceDO);
    }

    /**
     * @return purchasePrice 采购价格维护信息对象
     * @description 根据主键修改采购价格
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode updatePurchasePrice(PurchasePriceDO purchasePrice) throws Exception {
        // 设置价格存储值
        purchasePrice.setPrice(ToolPrice.storagPriceHandle(purchasePrice.getPrice()));
        // 修改改采购价格信息
        purchasePriceMapper.updateByExampleSelective(purchasePrice);

        return ErrorCode.Success;
    }

    /**
     * @return purchasePrice 采购价格维护信息对象
     * @description 删除采购价格
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode deletePurchasePrice(PurchasePriceDO purchasePrice) throws Exception {
        // 删除改采购价格信息
        purchasePriceMapper.delete(purchasePrice);

        return ErrorCode.Success;
    }

    /**
     * @return purchasePrice 采购价格维护信息对象
     * @description 批量删除采购价格
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode batchDeletePurchasePrice(List<PurchasePriceDO> priceList) throws Exception {
        // 删除改采购价格信息
        if (priceList != null) {
            for (PurchasePriceDO purchasePriceDO : priceList) {
                purchasePriceMapper.delete(purchasePriceDO);
            }
        }

        return ErrorCode.Success;
    }

    /**
     * @return purchasePrice 采购价格维护信息对象
     * @description 新增采购价格
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode addPurchasePrice(PurchasePriceDO purchasePrice) throws Exception {
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }

        // 设置采购价格主键
        purchasePrice.setId(textResult.getValue());

        // 新增改采购价格信息
        purchasePriceMapper.insert(purchasePrice);

        return ErrorCode.Success;
    }

    /**
     * @param in       文件流
     * @param orgId    企业标识
     * @param userId   用户ID
     * @param userName 用户名
     * @return
     * @throws Exception
     * @description <批量导入采购价格>
     */
    @Transactional(rollbackFor = Exception.class)
    public FunctionResult importPurchasePrice(InputStream in, String orgId, String userId, String userName) throws Exception {
        FunctionResult result = new FunctionResult();
        HSSFWorkbook wb = new HSSFWorkbook(in);
        HSSFSheet sheet = wb.getSheetAt(0);

        int totalRow = sheet.getLastRowNum();
        if (totalRow < 2) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        int totalCell = sheet.getRow(1).getLastCellNum();
        if (totalCell != 4) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }

        // 采购价格详情集合
        List<PurchasePriceDO> priceList = new ArrayList<PurchasePriceDO>();
        // 格式异常数据集合
        List<PurchasePriceDO> errorDetailVOList = new ArrayList<PurchasePriceDO>();

        for (int i = 2; i <= totalRow; i++) {
            HSSFRow curRow = sheet.getRow(i);
            PurchasePriceDO errorInfo = new PurchasePriceDO();

            // 零件编号
            String materialsNo = getCellValue(curRow, 0);
            // 供应商代码
            String supplierOrgId = getCellValue(curRow, 1);
            // 采购价格
            String price = getCellValue(curRow, 2);
            // 新增或更新
            String flag = getCellValue(curRow, 3);
            // 是否暂估价
            String provisionalPrice = getCellValue(curRow, 4);

            // 零件编号、计划数量、采购方式不能为空
            if (StringUtil.isNullOrEmpty(materialsNo) && StringUtil.isNullOrEmpty(supplierOrgId) && StringUtil.isNullOrEmpty(price) && StringUtil.isNullOrEmpty(flag)) {
                continue;
            }

            // 校验零件编码
            if (StringUtil.isNullOrEmpty(materialsNo)) {
                errorInfo.setErrorRow(i + 1);
                errorInfo.setRemark("零件编码不能为空");
                errorDetailVOList.add(errorInfo);
                continue;
            }
            MaterialsVO materialsVO = materialsService.itemByNo(materialsNo, orgId);
            if (materialsVO == null) {
                errorInfo.setErrorRow(i + 1);
                errorInfo.setRemark("零件不存在");
                errorDetailVOList.add(errorInfo);
                continue;
            }

            // TODO 校验供应商代码
            if (StringUtil.isNullOrEmpty(supplierOrgId)) {
                errorInfo.setErrorRow(i + 1);
                errorInfo.setRemark("供应商代码不能为空");
                errorDetailVOList.add(errorInfo);
                continue;
            }

            CompanySupplierDO companySupplierDO = companySupplierMapper.itemBySupplierOrgId(orgId, supplierOrgId);
            if (companySupplierDO == null) {
                errorInfo.setErrorRow(i + 1);
                errorInfo.setRemark("供应商不存在");
                errorDetailVOList.add(errorInfo);
                continue;
            }

            // 校验采购价格
            String priceCheckResult = checkPurchasePrice(price);
            if (priceCheckResult != null) {
                errorInfo.setErrorRow(i + 1);
                errorInfo.setRemark(priceCheckResult);
                errorDetailVOList.add(errorInfo);
                continue;
            }

            // 获取主键
            ActionResult<String> textResult = fastGenClient.textGuid();
            if (textResult.getCode() != ErrorCode.Success.getCode()) {
                result.setValue(errorDetailVOList);
                result.setCode(ErrorCode.IllegalArument);
                return result;
            }

            // 设置采购价格主键
            if ("0".equals(flag)) {

                PurchasePriceDO _purchasePrice = new PurchasePriceDO();
                _purchasePrice.setMaterialsNo(materialsNo);
                _purchasePrice.setSupplierOrgId(supplierOrgId);
                _purchasePrice.setOrgId(orgId);
                List<PurchasePriceDO> list = purchasePriceMapper.list(_purchasePrice);
                if (null != list && list.size() > 0) {
                    errorInfo.setErrorRow(i + 1);
                    errorInfo.setRemark("零件与供应商关系已存在");
                    errorDetailVOList.add(errorInfo);
                    continue;
                }

                PurchasePriceDO purchasePrice = getPriceDefaultVal(orgId, userId, userName);
                purchasePrice.setId(textResult.getValue());
                purchasePrice.setPrice(ToolPrice.storagPriceHandle(new BigDecimal(price)));
                purchasePrice.setMaterialsNo(materialsNo);
                purchasePrice.setMaterialsDes(materialsVO.getMaterialsDes());
                purchasePrice.setMaterialsType(materialsVO.getMaterialsType());
                purchasePrice.setUnit(materialsVO.getUnit());
                purchasePrice.setReplaceMaterialsNo(materialsVO.getReplaceMaterialsNo());
                purchasePrice.setReplaceMaterialsDes(materialsVO.getReplaceMaterialsDes());
                purchasePrice.setSupplierCode(companySupplierDO.getSupplierCode());
                purchasePrice.setSupplierName(companySupplierDO.getCompanyName());
                purchasePrice.setSupplierOrgId(companySupplierDO.getSupplierOrgId());
                purchasePrice.setSupplierClassId(companySupplierDO.getSupplierClassId());
                purchasePrice.setClassName(companySupplierDO.getSupplierClassName());
                purchasePrice.setProvisionalPrice(Integer.valueOf(provisionalPrice));
                priceList.add(purchasePrice);
            } else if ("1".equals(flag)) {
                PurchasePriceDO purchasePrice = new PurchasePriceDO();
                purchasePrice.setMaterialsNo(materialsNo);
                purchasePrice.setSupplierOrgId(supplierOrgId);
                purchasePrice.setOrgId(orgId);
                purchasePrice.setPrice(ToolPrice.storagPriceHandle(new BigDecimal(price)));
                purchasePrice.setProvisionalPrice(Integer.valueOf(provisionalPrice));
                purchasePriceMapper.updatePriceByMaterialsNoAndSupplierOrgId(purchasePrice);
            }

        }

        // 批量插入
        if (errorDetailVOList.isEmpty() && priceList.size() > 0) {
            for (PurchasePriceDO purchasePrice : priceList) {
                addPurchasePrice(purchasePrice);
            }
        }

        // 判断校验和添加数据入库是否全部成功
        if (ListUtil.isNullOrEmpty(errorDetailVOList)) {
            result.setValue(priceList);
            result.setCode(ErrorCode.Success);
        } else {
            result.setValue(errorDetailVOList);
            result.setCode(ErrorCode.IllegalArument);
        }
        return result;
    }

    private String getCellValue(HSSFRow curRow, int i) {
        String value = "";
        if (curRow.getCell(i) != null) {
            curRow.getCell(i).setCellType(CellType.STRING);
            value = curRow.getCell(i).getStringCellValue();
        }
        return value;
    }

    /**
     * @param orgId    企业标识
     * @param userId   用户ID
     * @param userName 用户名称
     * @return PurchasePrice 返回类型
     * @description <设置采购价格的默认值>
     */
    private PurchasePriceDO getPriceDefaultVal(String orgId, String userId, String userName) {
        PurchasePriceDO purchasePrice = new PurchasePriceDO();
        purchasePrice.setOrgId(orgId);
        purchasePrice.setCreatorId(userId);
        purchasePrice.setCreatorName(userName);
        purchasePrice.setCreateTime(new Date());
        purchasePrice.setModifierId(userId);
        purchasePrice.setModifierName(userName);
        purchasePrice.setModifyTime(new Date());
        purchasePrice.setDeleteFlag(0);

        return purchasePrice;
    }

    /**
     * @param price
     * @return
     * @return String 返回类型
     * @description <校验采购价格格式>
     */
    private String checkPurchasePrice(String price) {
        if (null == price || "".equals(price)) {
            return "采购价格不能为空";
        }

        try {
            BigDecimal decimal = new BigDecimal(price);
            if (decimal.compareTo(BigDecimal.ZERO) == 0) {
                return "采购价格不能为0";
            }
            if (new BigDecimal(price).compareTo(BigDecimal.valueOf(9999999.99)) > 0) {
                return "采购价格过搞";
            }
            if (price.contains(".") && price.substring(price.indexOf(".") + 1, price.length()).length() > 2) {
                return "采购价格小数点后最多只能输入两位";
            }
        } catch (Exception e) {
            return "采购价格格式不正确";
        }
        return null;
    }


    public void download() throws Exception {
        FileUtil.downLoadFile(response, filePath, templateExcelFileName);
    }
}
